<!--* 下拉树选择框组件-->
<!--* @module src/components/public-->
<!--* @desc 下拉树选择框-->
<!--* @author chenyi-->
<!--* @date 2019年08月15日17:22:43-->

<template>
  <div class="es-tree-content " v-clickoutside="hideTree">
    <div class="el-form-item__content" @click="clickInput">
      <div class="el-select tree" style="width: 100%;">
        <div class="el-input el-input el-input--suffix">
          <input type="text" v-model="valueName" readonly="readonly" autocomplete="off" placeholder="请选择"
                 class="el-input__inner">
          <span class="el-input__suffix"><span class="el-input__suffix-inner">
            <i :class="['el-select__caret', 'el-input__icon', 'el-icon-' + iconClass]"></i>
    </span></span>
        </div>
      </div>
    </div>
    <transition
      name="el-zoom-in-top"
    >
      <div class="es-tree"
           v-loading="loading"
           element-loading-text="数据加载中"
           v-show="showTree"
           :style="'padding-top:'+(showSearch===true?45:5)+'px'"
      >
        <el-input class="filter-text" v-if="showSearch" @focus.stop="" placeholder="输入关键字进行过滤" v-model="filterText"
                  clearable></el-input>
        <el-scrollbar style="height:300px">
          <!--复选-->
          <el-tree v-if="showCheckbox"
                   :data="list"
                   :ref="ref"
                   :default-checked-keys="value"
                   :filter-node-method="filterNode"
                   node-key="value"
                   show-checkbox
                   @check-change="handleCheckChange"
                   :default-expanded-keys="expandedIds"
          >
          </el-tree>
          <!--单选-->
          <el-tree v-else
                   :data="list"
                   :ref="ref"
                   :filter-node-method="filterNode"
                   node-key="value"
                   @node-click="handleNodeClick"
                   :default-expanded-keys="expandedIds"
          >
          </el-tree>
        </el-scrollbar>
        <el-row style="text-align: center;padding-top: 5px;">
          <el-button type="primary" v-if="url" size="mini" @click="refreshData">刷新</el-button>
          <el-button size="mini" @click="resetValue">重置</el-button>
          <el-button type="primary" size="mini" @click="showTree = false">确认</el-button>
        </el-row>

      </div>

    </transition>
  </div>
</template>

<script>
  import Clickoutside from 'element-ui/src/utils/clickoutside'
  import {getDataByUrl} from '../../api/getComData'

  export default {
    name: 'es-tree',
    directives: {Clickoutside},
    props: {
      showCheckbox: Boolean//是否多选
      , url: String //url
      , data: Array//json数组
      , value: [String, Number, Array]
      , collapseTags: Boolean //多选按文字显示
      , showSearch: Boolean //是否显示搜索框
      , disabled: Boolean//是否禁用
      , expandRoot: Boolean//是否展开根节点
    },
    model: {
      event: 'changeValue'
    },
    data: function () {
      return {
        ref: 'ref' + this.$t.getUUID(16, 16),
        loading: false,
        list: [],
        dataMap: {},
        showTree: false,
        values: this.value,
        valueName: '',
        filterText: '',
        expandedIds: []//默认展开的节点
      }
    },
    watch: {
      value: function (val) {
        if (!val) {
          this.values = this.showCheckbox ? [] : '';
          this.valueName = '';
          return
        }
        let _this = this;
        this.values = val;
        let isArray = typeof val === 'object';
        let checkedKeys = !isArray ? [val] : val;
        this.$refs[this.ref].setCheckedKeys(checkedKeys);
        if (isArray) {
          if (_this.showCheckbox) {
            _this.valueName = '';
            if (_this.collapseTags) {
              _this.valueName = '已选择' + val.length + '项'
            } else {
              for (let i = 0; i < val.length; i++) {
                if (!val[i]) {
                  continue
                }
                _this.valueName += _this.dataMap[val[i]].label;
                if (i < val.length - 1) {
                  _this.valueName += ','
                }
              }
            }
          } else {
            _this.valueName = _this.dataMap[_this.values].label
          }
        } else {
          this.valueName = _this.dataMap[_this.values].label
        }
      },
      values: function (val) {
        this.$emit('changeValue', val)
      },
      filterText (val) {
        this.$refs[this.ref].filter(val)
      }
    },
    mounted () {
      let _this = this
      //设置数据源
      if (_this.url) {
        getDataByUrl(_this.url, {}).then(res => {
          if (res.code === 200) {
            _this.list = res.data;
            _this.initData()
          } else {
            _this.$message.error(res.data.msg)
          }
        })
      } else if (_this.data) {
        _this.list = _this.data;
        _this.initData()
      } else {
        _this.$message.error('未指定数据源')
        return false
      }

    },
    computed: {
      iconClass () {
        return (this.showTree ? 'arrow-up is-reverse' : 'arrow-up')
      },
    },
    methods: {
      //初始化数据
      initData () {
        let _this = this
        _this.setDataMap(_this.list)
        //数据回填
        if (_this.values) {
          if (_this.showCheckbox) {
            _this.valueName = ''
            if (_this.collapseTags) {
              _this.valueName = '已选择' + _this.values.length + '项'
            } else {
              for (let i = 0; i < _this.values.length; i++) {
                if (!_this.values[i]) {
                  continue
                }
                _this.valueName += _this.dataMap[_this.values[i]].label
                if (i < _this.values.length - 1) {
                  _this.valueName += ','
                }
              }
            }
          } else {
            _this.valueName = _this.dataMap[_this.values].label
          }
        }
      },
      // 刷新数据
      refreshData () {
        let _this = this
        _this.loading = true
        getDataByUrl(_this.url, {}).then(res => {
          if (res.code === 200) {
            _this.list = res.data
            this.initData()
            _this.loading = false
          } else {
            _this.$message.error(res.data.msg)
          }
        })
      },
      // 清空值
      resetValue () {
        this.values = this.showCheckbox ? [] : ''
        this.valueName = ''
      },
      //复选点击
      handleCheckChange: function (data, isChecked, childrenHasChecked) {
        if (!this.showCheckbox) {
          return false
        }
        let _this = this
        let checkedKeys = this.$refs[this.ref].getCheckedKeys()
        if (checkedKeys.length === 0) {
          _this.values = ''
          _this.valueName = '请选择'
        } else {
          _this.values = checkedKeys
          _this.valueName = '已选择' + checkedKeys.length + '项'
        }
      },
      //单选点击
      handleNodeClick: function (data, node, ele) {
        if (this.showCheckbox) {
          return false
        }
        this.values = data.value
        this.valueName = data.label

      },
      //搜索
      filterNode (value, data) {
        if (!value) return true
        return data.label.indexOf(value) !== -1

      },
      clickInput: function () {
        this.showTree = !this.showTree
      },
      hideTree: function () {
        this.showTree = false
      },
      //isChildren是否子节点 用于默认展开根节点
      setDataMap: function (data, isChildren) {
        let _this = this
        //保存map数据
        for (let i = 0; i < data.length; i++) {
          _this.expandRoot && !isChildren && _this.expandedIds.push(data[i].value)
          _this.dataMap[data[i].value] = data[i]
          if (data[i].children) {
            _this.setDataMap(data[i].children, true)
          }
        }
      },
    }
  }
</script>
<style>
  .filter-text input {
    border: none;
  }
</style>
<style scoped>
  .es-tree-content {
    position: relative;
  }

  .es-tree-content input {
    cursor: pointer;
  }

  .es-tree-content .es-tree {
    position: absolute;
    top: 40px;
    left: 0;
    width: 100%;
    transform-origin: center top 0;
    z-index: 2005;
    border: 1px solid #E4E7ED;
    border-radius: 4px;
    background-color: #FFF;
    -webkit-box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    padding: 6px 0;
    margin-top: 6px;
  }

  .es-tree-content .filter-text {
    z-index: 1;
    position: absolute;
    top: 0;
    left: 0;
  }
</style>
